use std::rc::Rc;
use crate::List::{Cons, Nil};

// 掘金文章: https://juejin.cn/post/7057399624364998664?searchId=20241023190346C0A369EF9D92738AC84E
// 中的案例:
    // 财宝
    #[derive(Debug)]
    struct Treasure {
        dubloons: u32,
    }
    #[derive(Clone, Debug)]
    struct TreasureMap {
        treasure: Rc<Treasure>
    }

    impl TreasureMap {
        fn new(treasure: Rc<Treasure> ) -> Self {
            TreasureMap {
                treasure: treasure
            }
        }
    }
    
    enum List {
        Cons(i32, Rc<List>),
        Nil
    }
    
    fn main() {
        // 掘金文章:
        let booty = Rc::new(Treasure { dubloons: 1000 });
        let botty2 = booty.clone();
        let map1 = TreasureMap::new(booty);
        let map2 = map1.clone();
        println!("map1.treasure{:?}", map1.treasure);
        println!("booty.dubloons{:?}", botty2.dubloons);
        println!("map2.treasure{:?}", map2.treasure);
        // 个人理解: 说白了就是, 使用Rc能够让我们不用太过于在意所有权, 减轻心智负担
        // let a = Cons(1, &Nil); // 如果让Cons中拿的是引用, &Nil会在a获得所有权之前就被丢弃
        // let a = Cons(1, Box::new(Cons(2, Box::new(Nil))));
        // let b = Cons(3, Box::new(a));
        // let c = Cons(4, Box::new(a)); // 如果这样写, 会提示所有权已经被转移(到b)
        
        // 改造:
        let a =Rc::new(Cons(1, Rc::new(Cons(2, Rc::new(Nil)))));
        println!("count1 is {}", Rc::strong_count(&a)); // 1
        let b = Rc::clone(&a);
        println!("count2 is {}", Rc::strong_count(&a)); // 2
        {
            let c = Rc::clone(&a);
            println!("count3 is {}", Rc::strong_count(&a)); // 3
        }
        println!("count4 is {}", Rc::strong_count(&a)); // 2
        // 智能指针Rc作用就在于: 当有一个数据被多个部分使用, 且无法确定哪个部分是最后一次使用的时候, 就可以将其所有权交给Rc
        // 其他要用的, 就找Rc借用, 同时, Rc内部会计算引用次数
    }
    
    
    // rc 可以让单个值拥有多个所有者，而他的引用计数, 会在为0的时候自动释放内存, rc也实现了drop trait, 所以在rc被释放的时候, 会自动调用drop方法
    // rc的clone方法, 会增加引用计数, 而不是复制数据, 所以rc的clone方法是非常高效的
    // rc通过不可变引用来共享数据, 所以rc不能修改数据, 如果需要修改数据, 可以使用rc的clone方法来创建一个新的rc, 然后修改新的rc的数据